package org.file5.dao.impl;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.file5.dao.BaseDao;
import org.file5.domain.BaseEntity;
import org.file5.domain.Entity2Entity;
import org.file5.domain.BaseEntity.STATUS;
import org.file5.domain.Entity2Entity.Relation;
import org.file5.util.DataBean;
import org.springframework.stereotype.Repository;

import com.google.appengine.api.datastore.QueryResultIterator;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@Repository("baseDao")
public class BaseDaoImpl implements BaseDao {
	private final Logger logger = Logger.getLogger(this.getClass());

	@Override
	public <E extends BaseEntity> E find(Class<E> entityClass, String uid) {
		E result = null;
		if (uid != null && !uid.isEmpty()) {
			Objectify ofy = ObjectifyService.begin();
			result = ofy.find(entityClass, uid);
		}
		return result;
	}

	@Override
	public <E extends BaseEntity> E find(Class<E> entityClass, Key<E> key) {
		E result = null;
		if (key != null) {
			Objectify ofy = ObjectifyService.begin();

			result = ofy.find(key);
		}
		return result;
	}

	@Override
	public <E extends BaseEntity> E addUpdate(E entity) {
		if (entity != null) {
			Objectify ofy = ObjectifyService.begin();
			ofy.put(entity);

			return entity;
		}
		return null;

	}

	@Override
	public <E extends BaseEntity> void remove(E entity) {
		Objectify ofy = ObjectifyService.begin();

		ofy.delete(entity);

	}

	@Override
	public <E extends BaseEntity> DataBean<E> getListByProperties(Class<E> entityClass, int startPosition,
			int maxResult, final Object... params) {
		DataBean<E> dataBean = new DataBean<E>();

		Objectify ofy = ObjectifyService.begin();
		Query<E> query = ofy.query(entityClass);
		if (params != null) {
			for (int i = 0; i < params.length;) {
				if (params[i + 1] != null) {
					query.filter((String) params[i], params[i + 1]);
				}
				i = i + 2;
			}
		}
		dataBean.setCount(query.countAll());
		query.offset(startPosition).limit(maxResult).order("-created");

		QueryResultIterator<E> iterator = query.iterator();
		while (iterator.hasNext()) {
			try {
				E e = iterator.next();
				dataBean.addDataE(e);
			} catch (Exception e) {

			}
		}
		return dataBean;
	}

	//
	// @Override
	// public <E extends BaseEntity> DataBean<E> getListBy(Class<E> entityClass,
	// int startPosition, int maxResult,BaseEntity.STATUS entityStatus) {
	// DataBean<E> dataBean = new DataBean<E>();
	//
	// Objectify ofy = ObjectifyService.begin();
	// Query<E> query = ofy.query(entityClass);
	// if (entityStatus != null) {
	// query.filter("status", entityStatus.name());
	// }
	// dataBean.setCount(query.countAll());
	// query.offset(startPosition).limit(maxResult).order("-created");
	//
	// //
	// // String cursorStr = request.getParameter("cursor");
	// // if (cursorStr != null)
	// // query.cursor(Cursor.fromWebSafeString(cursorStr));
	//
	// QueryResultIterator<E> iterator = query.iterator();
	// while (iterator.hasNext()) {
	// try {
	// E e = iterator.next();
	// dataBean.addDataE(e);
	// } catch (Exception e) {
	//
	// }
	// }
	// return dataBean;
	// }

	@Override
	public <E extends BaseEntity> void clearData(Class<E> entityClass) {
		Objectify ofy = ObjectifyService.begin();

		Query<E> query = ofy.query(entityClass);

		QueryResultIterator<E> iterator = query.iterator();
		while (iterator.hasNext()) {
			try {
				E e = iterator.next();
				ofy.delete(e);
			} catch (Exception e) {

			}
		}
	}

	@Override
	public <E extends BaseEntity, E2 extends BaseEntity> Entity2Entity<E, E2> findEntity2Entity(E entity,
			Relation relation, E2 entity2) {

		Entity2Entity<E, E2> result = null;
		DataBean<Entity2Entity<E, E2>> dataBean = this.getEntity2EntitiesBy(0, 1, entity, relation, entity2, null);
		if (dataBean != null && !dataBean.isEmpty()) {
			Iterator<Entity2Entity<E, E2>> it = dataBean.getData().iterator();
			result = it.next();
		}
		return result;
	}

	@Override
	public <E extends BaseEntity, E2 extends BaseEntity> DataBean<Entity2Entity<E, E2>> getEntity2EntitiesBy(
			int startPosition, int maxResult, E entity, Relation relation, E2 entity2, STATUS e2eStatus) {

		DataBean<Entity2Entity<E, E2>> dataBean = new DataBean<Entity2Entity<E, E2>>();

		Objectify ofy = ObjectifyService.begin();

		Query<Entity2Entity> query = ofy.query(Entity2Entity.class);
		if (entity != null) {
			query.filter("entityKey", entity);
		}
		if (relation != null) {
			query.filter("relation", relation.name());
		}
		if (entity2 != null) {
			query.filter("entity2Key", entity2);
		}
		if (e2eStatus != null) {
			query.filter("status", e2eStatus.name());
		}
		dataBean.setCount(query.countAll());
		query.offset(startPosition).limit(maxResult).order("-created");
		QueryResultIterator<Entity2Entity> iterator = query.iterator();
		while (iterator.hasNext()) {
			dataBean.addDataE(iterator.next());
		}
		return dataBean;
	}

	@Override
	public <E extends BaseEntity> E find(Key<E> key) {
		Objectify ofy = ObjectifyService.begin();
		if (key != null) {
			return ofy.find(key);
		}
		return null;
	}

}
